package base

import (
	"gitee.com/wm1998/infra"
	"github.com/go-playground/locales/zh"
	"github.com/go-playground/universal-translator"
	log "github.com/sirupsen/logrus"
	"gopkg.in/go-playground/validator.v9"
	vtzh "gopkg.in/go-playground/validator.v9/translations/zh"
)

var validate *validator.Validate // 对输入参数结构体成员Tag中使用了“validate”进行校验的Validator实例
func Validate() *validator.Validate {
	return validate
}

var translator ut.Translator // 对输入参数结构体成员Tag中使用了“validate”进行校验失败输出中文的翻译器
func Transtate() ut.Translator {
	return translator
}

type ValidatorStarter struct {
	infra.BaseStarter // 包含infra.BaseStarter接口，目的是可以选择性地实现该接口方法
}

// 实现了启动器管理器接口的此方法
func (v *ValidatorStarter) Init(ctx infra.StarterContext) {
	validate = validator.New() // 创建验证器

	//创建消息国际化通用翻译器
	cn := zh.New()        // 创建中文翻译器
	uni := ut.New(cn, cn) // 创建通用翻译器
	var found bool
	translator, found = uni.GetTranslator("zh") // 获取通用中文翻译器
	if found {
		err := vtzh.RegisterDefaultTranslations(validate, translator) // 将中文翻译器注册到验证器
		if err != nil {
			log.Error(err)
		}
	} else {
		log.Error("Not found translator: zh")
	}
}

// 提取公共校验结构体成员数据的函数
func ValidateStruct(s interface{}) (err error) {
	err = Validate().Struct(s) // 使用验证器验证结构体
	if err != nil {
		_, ok := err.(*validator.InvalidValidationError)
		if ok {
			log.Error("验证错误", err)
		}
		errs, ok := err.(validator.ValidationErrors) // 获取对结构体所有成员含有`validate`的Tag标签进行验证出错的切片
		if ok {
			for _, e := range errs {
				log.Error(e.Translate(Transtate()))
			}
		}
		return err
	}
	return nil
}
